#include "./app_alarm.h"
#include "./app_led.h"
#include "./app_adc.h"
#include "./app_can.h"
#include "./app_timer.h"
#include "./app_device.h"
#include "./app_flash.h"
uint32_t proFaultFlag = 0;
struct alram_dev_t *warn_device;//报警设备
uint16_t ioutMaxVal = 500,\
         voutMaxVal = 5500,\
				 voutMinVal = 2000,\
				 vinMaxVal = 300,\
				 vinMinVal = 5,\
				 tempMaxVal= 800 ,\
				 fanMaxVal = 500;
static struct alarm_obj_t tmp_obj;
static float th_val;
uint16_t voutMaxDefault;
//struct alram_setting_t 
//{
//     ;
//     ;
//     ;
//     ;
//     ;
//     ;
//};

/**
 * @brief 输出欠压保护 
 * 
 * @return uint8_t 0 正常 1 欠压保护
 */
static uint8_t alarm_vout_under(void)
{
 #if 1

    th_val = voutMinVal;
    th_val= th_val/10;//模块过压值
    if((VolVout <= th_val)&&(VolVout>300))     
    {
      
        return 1;
    }
		else
		{
			return 0;
		}
#else 
	return 1;
#endif
    
}
/**
 * @brief 输出过压保护 
 * 
 * @return uint8_t  0 正常 1 过压保护
 */
static uint8_t alarm_vout_over(void)
{
 #if 1
	  th_val = voutMaxVal;
    th_val= th_val/10;//模块过压值
    if(VolVout >=th_val)
    {        

        return 1;
    }
    return 0;
#else 
		return 1;
#endif
}
/**
 * @brief 输入欠压保护
 * 
 * @return uint8_t  0 正常 1 欠压保护
 */
static uint8_t alram_vin_under(void)
{
 #if 0
 
	th_val = vinMinVal;
    th_val= th_val/10;//模块过压值
    if(VolVin <= th_val)
    {

        return 1;
    }
    return 0;
#else
    return 0;
#endif 
}
/**
 * @brief 输入过压保护
 * 
 * @return uint8_t 0 正常 1 过压保护
 */
static uint8_t alram_vin_over(void)
{
 #if 0
 
	th_val = vinMaxVal;
    th_val= th_val/10;//模块过压值
    if(VolVin >= th_val)
    {

        return 1;
    }

    return 0;
#else
	return 0;
#endif
}
/**
 * @brief 输出过流保护
 * 
 * @return uint8_t 0 正常 1 过流保护
 */
static uint8_t alram_iout_over(void)
{
 #if 0

	th_val = ioutMaxVal;
    th_val= th_val/10;//模块过压值
    if(VolIout >= th_val)
    {
       ;
        return 1;
    }

    return 0;
#else
		return 0;
#endif

}
/**
 * @brief 过温保护
 * 
 * @return uint8_t 0 正常 1 过温保护 
 */
uint16_t test_temp = 0;
static uint8_t alram_temp_over(void)
{ 
#if 1
	  th_val = tempMaxVal;
    th_val= th_val/10;//模块过压值
    if(VolTemp >= th_val)
    {
        
        return 1;
    }
    return 0;
#else 
	return 1;
#endif
}
/**
 * @brief 通信异常保护
 * 
 * @return uint8_t  0 正常 1 通信异常
 */
static uint8_t alram_comm_error(void)
{
#if 1
    if((comm_dev->check_running(comm_dev))>0)
    {
        return 0;
    }
		else
		{
			return 1;
		}
    return 0;
#else 
	return 1;
#endif 
}
/**
 * @brief 风扇故障保护
 * 
 * @return uint8_t 
 */
static uint8_t alram_fan_error(void)
{
    return 0;
}
/*
bit: 0   输出欠压保护
     1   输出过压保护
     2   输入欠压保护
     3   输入过压保护 
     4   输出过流保护 
     5   过温保护
     6  通信异常保护
     7  风扇故障保护
*/
    
/**
 * @brief  保护函数初始化
 * 
 * @param dev 
 */
static void alarm_obj_init(struct alram_dev_t *dev)
{
    
    tmp_obj.type             = ALARM_OBJ_TYPE_DELAY;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        = ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0x1fff*10;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check           = alarm_vout_under ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_VOUT_UNDER);
    tmp_obj.type             = ALARM_OBJ_TYPE_DELAY;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code         =ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0x1fff;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alarm_vout_over  ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_VOUT_OVER);

    tmp_obj.type             = ALARM_OBJ_TYPE_IMM;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        =ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alram_vin_under  ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_VIN_UNDER);

    tmp_obj.type             = ALARM_OBJ_TYPE_IMM;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        =ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alram_vin_over   ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_VIN_OVER);

    tmp_obj.type            = ALARM_OBJ_TYPE_DELAY;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        = ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0x1fff;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alram_iout_over  ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_IOUT_OVER);

    tmp_obj.type             = ALARM_OBJ_TYPE_DELAY;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        = ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0x20ff;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alram_temp_over  ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_TEMP_OVER);

    tmp_obj.type            = ALARM_OBJ_TYPE_IMM;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        = ALRAM_TYPE_WARNING;
    tmp_obj.delay_cnt_val   = 0;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alram_comm_error ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_COM_ERROR);
    
    tmp_obj.type             = ALARM_OBJ_TYPE_IMM;//处理类型 0 无等待，1 有延时等待 0xff
    tmp_obj.err_code        = ALARM_TYPE_FALUT;
    tmp_obj.delay_cnt_val   = 0;//延迟计数设定值
    tmp_obj.delay_cnt       = 0;   // 延迟计数，每次执行-1，为0 时直接执行 
    tmp_obj.check = alram_fan_error ;
    dev->obj_init(dev,&tmp_obj,ALARM_FUNC_NUM_FAN_ERROR);

}
void app_alarm_init(void)
{
	alarm_init(&warn_device);
	alarm_obj_init(warn_device);
	voutMaxVal =app_load_vout_max();
	voutMinVal=app_load_vout_min();
	ioutMaxVal =app_load_iout_max();
	vinMaxVal=app_load_vin_max();
	vinMinVal=app_load_vin_min();
	tempMaxVal=app_load_temp_max();
	fanMaxVal=app_load_fan_max();
	voutMaxDefault = app_load_vout_max_default();
}
uint32_t rebotTimerCounters;
void app_alarm_loop_func(void)
{
    warn_device->loop_func(warn_device);//循环读取告警
    
    if(warn_device->fault_num>0)//异常警告 
    {
        lamp->modify_state(lamp,LED_NUM_ALARMED,LED_STATE_BLK);  
	      mod_device->set_power(mod_device,0);
#if 0
				if((warn_device->fault_flag_buf[0])&(1<<ALARM_FUNC_NUM_IOUT_OVER))//有电流
				{
						if((warn_device->fault_flag_buf[0])&(~(1<<ALARM_FUNC_NUM_IOUT_OVER)))//有其他告警
						{
								mod_device->set_power(mod_device,0);
						}
						else
						{
								//mod_device->set_power(mod_device,1);//只有过流
						}
				}
				else
				{
					 mod_device->set_power(mod_device,0);
				}
#endif
    }
    else
    {
        if(proFaultFlag > 0)//恢复异常，获取当前时间
        { 
            rebotTimerCounters= get_global_timer();//获取当前时间  
            rebotTimerCounters +=60 ;

        }
        else//开始倒计时准备重启
        {
            if(rebotTimerCounters==get_global_timer())//时间到
            {
                lamp->modify_state(lamp,LED_NUM_ALARMED,LED_STATE_OFF);//设置为关闭状态  
                mod_device->set_power(mod_device,1);        
            }
        }
    }
    proFaultFlag = warn_device->fault_num;
    if(warn_device->warn_num>0)//故障警告
    {
        lamp->modify_state(lamp,LED_NUM_WARNING,LED_STATE_BLK);
    }
    else
    {
       lamp->modify_state(lamp,LED_NUM_WARNING,LED_STATE_OFF);//设置为关闭状态
    }
    warn_device->clear_flaut_num(warn_device);
    warn_device->clear_warn_num(warn_device);
}

